package org.kitten.core.util;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.DOMBuilder;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.jdom.xpath.XPath;

public class JDomUtil {
	public static int FORMAT_PRETTY = 0;
	public static int FORMAT_COMPACT = 1;

	// private static XMLOutputter xmlOutput = new XMLOutputter();

	/**
	 * 将Document对象转化为字符串
	 * 
	 * @param doc
	 * @return
	 */
	public static String outputString(Document doc) {
		return outputString(doc, null);
	}

	public static String outputString(Document doc, String encoding) {
		XMLOutputter xmlOutput = null;
		if (encoding != null) {
			Format format = Format.getCompactFormat();
			format.setEncoding(encoding);
			xmlOutput = new XMLOutputter(format);
		} else {
			xmlOutput = new XMLOutputter();
		}
		String result = xmlOutput.outputString(doc);
		result = result.replaceAll("\n", "");
		result = result.replaceAll("\r", "");
		return result;
	}

	public static boolean save(Document doc, String filepath, String encoding,
			int fmt) throws IOException {
		boolean ret = false;
		Format format = (fmt == FORMAT_PRETTY ? Format.getPrettyFormat()
				: Format.getCompactFormat());
		if (encoding != null) {
			format.setEncoding(encoding);
		}
		XMLOutputter xmlOutput = new XMLOutputter(format);
		String result = xmlOutput.outputString(doc);

		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(filepath);
			fos.write(result.getBytes(encoding));
			ret = true;
		} catch (IOException e) {
			throw e;
		} finally {
			FileUtil.close(fos);
		}
		return ret;
	}

	public static String outputString(org.w3c.dom.Document domDocument) {
		DOMBuilder builder = new DOMBuilder();
		org.jdom.Document jdom = builder.build(domDocument);
		return outputString(jdom, "UTF-8");
	}

	public static Element selectSingleNode(Document doc, String path) throws JDOMException {
		Element node = null;
		XPath xpath = XPath.newInstance(path);
		node = (Element) xpath.selectSingleNode(doc);
		return node;
	}

	public static List<Element> selectNodes(Document doc, String path)
			throws JDOMException {
		List<Element> nodeList = new ArrayList<Element>();
		nodeList = XPath.selectNodes(doc, path);
		return nodeList;
	}

	/**
	 * 将document字符串转化为dom对象
	 * 
	 * @param docString
	 * @return
	 * @throws IOException
	 * @throws JDOMException
	 */
	public static Document buildDocumentFromString(String docString)
			throws JDOMException, IOException {
		if (docString == null)
			return null;
		ByteArrayInputStream bin = new ByteArrayInputStream(docString
				.getBytes());
		SAXBuilder sax = new SAXBuilder();
		Document doc = null;
		doc = sax.build(bin);
		return doc;
	}

	public static Document buildDocumentFromFile(String filepath)
			throws JDOMException, IOException {
		Document doc = null;
		SAXBuilder sax = new SAXBuilder(false);
		sax
				.setFeature(
						"http://apache.org/xml/features/nonvalidating/load-external-dtd",
						false);
		doc = sax.build(new File(filepath));
		return doc;
	}

	public static Document buildDocumentFromInputStream(InputStream is)
			throws JDOMException, IOException {
		Document doc = null;
		SAXBuilder sax = new SAXBuilder(false);
		sax
				.setFeature(
						"http://apache.org/xml/features/nonvalidating/load-external-dtd",
						false);
		doc = sax.build(is);
		return doc;
	}

	/**
	 * 从document的根结点的子结点中找出第一个属性名为attributeName，属性值为attributeValue的结点
	 * 
	 * @param doc
	 * @param attributeName
	 * @param attributeValue
	 * @param nodeName
	 *            结点名称，如果为空，不管什么结点，只要属性名等于指定值;如果不为空，取结点名称为指定值，属性名为指定值的结点
	 * @return
	 */
	public static Element getNodeByAttribute(Document doc,
			String attributeName, String attributeValue, String nodeName) {
		Element result = null;
		if (doc == null)
			return result;
		Element root = doc.getRootElement();
		List nodes = root.getChildren();
		for (Iterator iterator = nodes.iterator(); iterator.hasNext();) {
			Element node = (Element) iterator.next();
			if (nodeName != null && !nodeName.equals(node.getName()))
				continue;
			if (attributeValue.equalsIgnoreCase(node
					.getAttributeValue(attributeName))) {
				result = node;
				break;
			}

		}
		return result;
	}

	/**
	 * 找出父结点的子结点中，属性值与指定值相等的第一个子结点
	 * 
	 * @param parentNode
	 * @param attributeName
	 * @param attributeValue
	 * @return
	 */
	public static Element getNodeByAttribute(Element parentNode,
			String attributeName, String attributeValue) {
		Element result = null;
		List nodes = parentNode.getChildren();
		for (Iterator iterator = nodes.iterator(); iterator.hasNext();) {
			Object obj = iterator.next();

			Element node = (Element) obj;
			if (attributeValue.equalsIgnoreCase(node
					.getAttributeValue(attributeName))) {
				result = node;
				break;
			}

		}
		return result;
	}
}
